package scrum.client.project;

import ilarkesto.gwt.client.AMultiSelectionViewEditWidget;
import ilarkesto.gwt.client.AOutputViewEditWidget;
import ilarkesto.gwt.client.AnchorPanel;
import ilarkesto.gwt.client.TableBuilder;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import scrum.client.Dao;
import scrum.client.ScrumGwt;
import scrum.client.admin.User;
import scrum.client.common.ABlockWidget;
import scrum.client.common.BlockHeaderWidget;
import scrum.client.common.BlockWidgetFactory;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;

public class ProjectGroupBlock extends ABlockWidget<ProjectGroup> {

	private AnchorPanel iconWrapper;

	@Override
	protected void onInitializationHeader(BlockHeaderWidget header) {
		ProjectGroup projectGroup = getObject();
		iconWrapper = header.addIconWrapper();
		header.addText(projectGroup.getLabelModel());
		header.addText(projectGroup.getLastCommentAgoModel(), true);
		header.addMenuAction(new DeleteProjectGroupAction(projectGroup));
	}

	@Override
	protected void onUpdateHeader(BlockHeaderWidget header) {
		ProjectGroup projectGroup = getObject();
		header.setDragHandle("group");
		Image icon = null;
		// if (projectGroup.is()) {
		// icon = Img.bundle.usrDisabled().createImage();
		// icon.setTitle("User is disabled.");
		// } else if (!projectGroup.isEmailVerified()) {
		// icon = Img.bundle.usrEmailUnverified().createImage();
		// icon.setTitle("Users email is not verified.");
		// }
		iconWrapper.setWidget(icon);
	}

	@Override
	protected Widget onExtendedInitialization() {
		final ProjectGroup projectGroup = getObject();
		TableBuilder tb = ScrumGwt.createFieldTable();
		tb.addFieldRow("Name", projectGroup.getLabelModel());
		tb.addFieldRow("Description", projectGroup.getDescriptionModel());
		tb.addFieldRow("Linked Project", new AOutputViewEditWidget() { // needed to be created like this to

																		// make this field "read-only"
			@Override
			protected void onViewerUpdate() {
				setViewer(new Label(projectGroup.getProject().getLabel()));
			}
		});

		// tb.addFieldRow("Linked Project",projectGroup.getProject().getLabelModel()); //this way of creating
		// the field don't allow to make it "read-only" =>

		// UserStories allowed for the group
		tb.addFieldRow("User Stories this group will work with", new AMultiSelectionViewEditWidget<Requirement>() {

			@Override
			protected void onViewerUpdate() {
				List<Requirement> associatedStories = new ArrayList<Requirement>(projectGroup.getStoriesAssociates());
				Collections.sort(associatedStories);
				setViewerItemsAsHtml(associatedStories);
			}

			@Override
			protected void onEditorUpdate() {
				List<Requirement> reqs = Dao.get().getRequirements();
				Collections.sort(reqs);
				setEditorItems(reqs);
				setEditorSelectedItems(projectGroup.getStoriesAssociates());
			}

			@Override
			protected void onEditorSubmit() {
				// checkear si las user stories fueron seleccionadas ya para otro grupo!!!
				List<Requirement> selected = getEditorSelectedItems();
				List<Requirement> alreadySelected = new ArrayList<Requirement>();

				for (Requirement requirement : selected) {
					if (isAssociatedToOtherGroup(requirement)) alreadySelected.add(requirement);
				}

				if (alreadySelected.isEmpty())
					projectGroup.setStoriesAssociates(getEditorSelectedItems());
				else {
					String errorMsg = "ERROR. ";
					if (alreadySelected.size() == 1)
						errorMsg += "The user storie |" + alreadySelected.get(0).getReference() + "| is ";
					else {
						errorMsg += "The user stories ";
						for (Requirement r : alreadySelected)
							errorMsg += "| " + r.getReference() + " |";
						errorMsg += " are ";
					}
					Window.alert(errorMsg + "already associated to another group in this project.");
				}
			}

			@Override
			public boolean isEditable() {
				return projectGroup.isEditable();
			}

			public boolean isAssociatedToOtherGroup(Requirement r) {
				List<ProjectGroup> groups = getDao().getProjectGroupsByProject(projectGroup.getProject());
				groups.remove(projectGroup); // remove this group from the list
				boolean associated = false;
				for (int i = 0; i < groups.size() && !associated; i++) {
					associated = groups.get(i).containsStoriesAssociate(r);
				}
				return associated;
			}
		});
		// Group Members
		tb.addFieldRow("Group Members", new AMultiSelectionViewEditWidget<User>() {

			@Override
			protected void onViewerUpdate() {
				setViewerItemsAsHtml(projectGroup.getGroupMembers());
			}

			@Override
			protected void onEditorUpdate() {
				List<User> projectParticipants = new ArrayList<User>(projectGroup.getProject().getParticipants());
				Set<User> alreadyMembers = projectGroup.getGroupMembers();

				Collections.sort(projectParticipants);
				setEditorItems(projectParticipants);
				setEditorSelectedItems(alreadyMembers);
			}

			@Override
			protected void onEditorSubmit() {
				projectGroup.setGroupMembers(getEditorSelectedItems());

				// falta un check para ver que una persona no esté en más de un mismo grupo de ese proyecto.
			}

			@Override
			public boolean isEditable() {
				return projectGroup.getProject().isEditable();
			}
		});
		return tb.createTable();
	}

	public static final BlockWidgetFactory<ProjectGroup> FACTORY = new BlockWidgetFactory<ProjectGroup>() {

		@Override
		public ProjectGroupBlock createBlock() {
			return new ProjectGroupBlock();
		}
	};
}
